use std::str::FromStr;

use crate::{middleware::jwt::admin::Claims, utils};
use axum::{
    body::Body,
    extract::{Query, State},
    http::Response,
    response::IntoResponse,
    Json,
};
use sky_pojo::{
    dto,
    vo::report::{OrderReportVO, SalesTop10ReportVO, TurnoverReportVO, UserReportVO},
};

use crate::{bootstrap::AppState, router::resp::RespVO, service};

pub async fn turnover_statistics(
    State(state): State<AppState>,
    _claim: Claims,
    Query(dto): Query<dto::report::ReportDateDTO>,
) -> Response<Body> {
    let begin = utils::parse_date(&dto.begin, "%Y-%m-%d").unwrap();
    let end = utils::parse_date(&dto.end, "%Y-%m-%d").unwrap();

    match service::report::get_turnover(&state.db_pool, begin, end).await {
        Ok(vo) => {
            RespVO::<TurnoverReportVO>::success("success".to_string(), Some(vo)).into_response()
        }
        Err(e) => RespVO::<()>::error_without_data(e).into_response(),
    }
}

pub async fn user_statistics(
    State(state): State<AppState>,
    _claim: Claims,
    Query(dto): Query<dto::report::ReportDateDTO>,
) -> Response<Body> {
    let begin = utils::parse_date(&dto.begin, "%Y-%m-%d").unwrap();
    let end = utils::parse_date(&dto.end, "%Y-%m-%d").unwrap();
    match service::report::get_user_statistics(&state.db_pool, begin, end).await {
        Ok(vo) => RespVO::<UserReportVO>::success("success".to_string(), Some(vo)).into_response(),
        Err(e) => RespVO::<()>::error_without_data(e).into_response(),
    }
}

pub async fn order_statistics(
    State(state): State<AppState>,
    _claim: Claims,
    Query(dto): Query<dto::report::ReportDateDTO>,
) -> Response<Body> {
    let begin = utils::parse_date(&dto.begin, "%Y-%m-%d").unwrap();
    let end = utils::parse_date(&dto.end, "%Y-%m-%d").unwrap();

    let vo = service::report::get_order_statistics(&state.db_pool, begin, end).await;

    RespVO::<OrderReportVO>::success("success".to_owned(), Some(vo)).into_response()
}

pub async fn top_10(
    State(state): State<AppState>,
    _claim: Claims,
    Query(dto): Query<dto::report::ReportDateDTO>,
) -> Response<Body> {
    let begin = utils::parse_date(&dto.begin, "%Y-%m-%d").unwrap();
    let end = utils::parse_date(&dto.end, "%Y-%m-%d").unwrap();

    let top_10 = match service::report::top_10(&state.db_pool, begin, end).await {
        Ok(o) => o,
        Err(e) => return RespVO::<()>::error_without_data(e).into_response(),
    };

    RespVO::<SalesTop10ReportVO>::success("success".to_owned(), Some(top_10)).into_response()
}
